package org.bridgen.runtime.inspect;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;

import org.bridgen.runtime.RecoveryLexer;

/**
 * 
 * @author Emma Söderberg <emma add cs.lth.se>
 *
 */

public class SampleFactory {
	private ArrayList<Sample> sampleNames;
	private HashMap<String, RecoveryLexer> lexerHash;
	
	public SampleFactory(HashMap<String, RecoveryLexer> lexerHash, String path) {
		this.lexerHash = lexerHash;
		sampleNames = loadSampleNames(path);
	}	

	public SampleFactory(HashMap<String, RecoveryLexer> lexerHash) {
		this.lexerHash = lexerHash;
		sampleNames = loadSampleNames(null);
	}

	public Object[] getSampleNames() {
		return sampleNames.toArray();
	}

	public StringBuffer getFileContent(Sample sample) {
		StringBuffer buf = new StringBuffer();
		try {
			buf = readFile(sample.file);
		} catch(IOException e) {
			System.out.println("Problem reading file: " + e.getMessage());
		}
		return buf;
	}
	
	public ArrayList<Sample> loadSampleNames(String path) {
		ArrayList<Sample> sampleList = new ArrayList<Sample>();
		if (path == null)
			path = "./testsuit/";
		File dir = new File(path);
		if (dir.exists()) {
			ArrayList<File> fileList = new ArrayList<File>();
			collectFiles(fileList, dir);
			for (Iterator<File> itr = fileList.iterator(); itr.hasNext();) {
				File file = itr.next();
				RecoveryLexer lexer = lexerHash.get("java"); // TODO Change to something less java specific
				if (lexer != null) {
					sampleList.add(new Sample(file, lexer));
				}
			}
			Collections.sort(sampleList);
		}
		return sampleList;
	}
     private static void collectFiles(ArrayList<File> fileList, File dir) {
         if (dir.isDirectory()) {
             File[] childFile = dir.listFiles();
             for (int i = 0; i < childFile.length; i++) {
                 if (childFile[i].isDirectory()) {
                     collectFiles(fileList, childFile[i]);
                 } else if (filterOk(childFile[i])) {
                     fileList.add(childFile[i]);
                 }
             }
         }
     }
 
     private static boolean filterOk(File file) {
		 return file.getAbsolutePath().contains("break") || file.getAbsolutePath().contains("chunk");
    //     return file.getAbsolutePath().endsWith("java");
     }

	private StringBuffer readFile(File file) throws IOException {
		StringBuffer sb = new StringBuffer();
		BufferedReader reader = new BufferedReader(new FileReader(file));				
		char[] chars = new char[1024];
		int read = 0;
		while((read = reader.read(chars)) > -1){
			sb.append(String.valueOf(chars, 0, read));
		}
		reader.close();
		return sb;
	}

	public static class Sample implements Comparable<Sample> {
		String name;
		File file;
		String filePath;
		RecoveryLexer lexer;
		public Sample(File file, RecoveryLexer lexer) {
			this.lexer = lexer;
			this.file = file;
			this.filePath = file.getAbsolutePath();
			int index = filePath.lastIndexOf("/");
			if (index > 0) {
				name = filePath.substring(index+1, filePath.length());
			} else { 
				name = filePath;
			}
		}
		public String toString() {
			return name;
		}
		public int compareTo(Sample sample) {
			return name.compareTo(sample.name);
		}
	}

}
